package db_main

import (
	"errors"
	"fmt"
	"gorm.io/gorm"
	global2 "longmen/server/config/global"
	"longmen/server/pkg/common/helper/const"
	"longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/db/mysql"
	"longmen/server/pkg/db/mysql/models/models_main"
)

func GetGiftParam(param map[string]interface{}) (*models_main.Gift, error) {
	fName := "GetGiftParam"
	o := &models_main.Gift{}
	table := global2.Live().Model(&models_main.Gift{})
	mysql.Condition(table, param, "", "", 0, 0)
	err := table.Take(o).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		err = nil
	}
	if err != nil {
		err = fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return o, err
}

func GetGiftsParam(param map[string]interface{}, order string) ([]*models_main.Gift, error) {
	fName := "GetGiftsParam"
	o := make([]*models_main.Gift, 0)
	table := global2.Live().Model(&models_main.Gift{})
	mysql.Condition(table, param, "", order, 0, 0)
	err := table.Find(&o).Error
	if err != nil {
		err = fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return o, err
}

func GetGiftsList() ([]*models_main.Gift, error) {
	fName := "GetGiftsParam"
	o := make([]*models_main.Gift, 0)
	// case when 是兼容老代码 所以才这样变的
	err := global2.Live().Raw("select id,title,icon,animation,case when type in(0) then 0 else animat_type end animat_type,duration,price,type,status,sort,price_type from db_gift where status=1 and type in(0,1,2) order by sort asc, id asc").Find(&o).Error

	if err != nil {
		err = fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return o, err
}

/**
 * @Author willi
 * @Description //new  noble 的名字没有加入到models 中
 * @Date 14:35 2022/9/14
 * @Param
 * @return
 **/
func GetGiftsParamNew(userId int) ([]*models_main.Gift, error) {
	o := make([]*models_main.Gift, 0)
	sql := "select t3.id,t3.title,t3.icon,t3.animation,t3.animat_type,t3.duration,t3.price,t3.type,t3.`status`,t3.sort,t3.price_type,t3.consecutive_num from live.db_gift t3 where t3.`status`=1"
	if userId > 0 {
		sql = fmt.Sprintf("select t3.id,t3.title,t3.icon,t3.animation,t3.animat_type,t3.duration,round(IF(t4.gift_discount is null,t3.price*1,t3.price*t4.gift_discount),0) price,t3.type,t3.`status`,t3.sort,t3.price_type,t3.consecutive_num,t4.`name`  from live.db_gift t3 left join (SELECT gift_discount/100 gift_discount,`name` FROM main.`db_noble_new` t1,main.db_noble_record t2 where t2.noble_id=t1.id and  t2.uid=%d and expiration>unix_timestamp(now()) ORDER BY t1.id desc LIMIT 1 )t4 on 1=1 where t3.`status`=1", userId)
	}
	err := global2.Live().Raw(sql).Find(&o).Error
	return o, err
}

/*
*
todo:这里做为主记录放在主库里，把gift_log放到live
*/
func UserBuyGiftByTx(gift models_main.GiftLog, session *gorm.DB) {
	fName := "6UserBuyGiftByTx9"
	userProfit := &models_main.UserProfit{
		//(uid, -giftPrint, fundsType, util.CONSUME_GIFT)
		Uid:         gift.Uid,            //送的人
		FUid:        gift.Anchorid,       //得的人
		CoinCount:   -gift.Spend,         //总价格
		Type:        _const.TYPE_CONSUME, //这是一个消费记录
		ConsumeType: _const.CONSUME_GIFT,

		Content: fmt.Sprintf("赠送主播(ID:%d)礼物ID:%dx%d 消费%d%s",
			gift.Anchorid, gift.Giftid, gift.Count, gift.Spend/100, util.GetCoinName(gift.SpendType)),

		Resid:      gift.Giftid,
		Count:      gift.Count,
		CreateTime: gift.CreateTime,
		CoinType:   gift.SpendType,

		OrderNo: util.GenOrderId("GS", 1),
		Liveid:  gift.Liveid,
	}
	var profitLog []*models_main.UserProfit
	global2.Log.Debugf("%s写收益记录送礼方:%v", fName, userProfit)
	profitLog = append(profitLog, userProfit)

	if err := InsertUserProfitByTransactions(session, profitLog); err != nil {
		global2.Log.Error("%s送礼收益记录写入失败:%v", fName, profitLog)
	}
}

/*
*
@Origin: Spicy
@提取: Enzo July 1 2022
*/
func UserProfitFromGift(gift models_main.GiftLog) {
	fName := "6UserProfitFromGift9"
	userProfit := &models_main.UserProfit{
		//(uid, -giftPrint, fundsType, util.CONSUME_GIFT)
		Uid:         gift.Uid,            //送的人
		FUid:        gift.Anchorid,       //得的人
		CoinCount:   -gift.ActualSpend,   //总价格
		Type:        _const.TYPE_CONSUME, //这是一个消费记录
		ConsumeType: _const.CONSUME_GIFT,

		Content: fmt.Sprintf("赠送主播(ID:%d)礼物ID:%dx%d 消费%d%s",
			gift.Anchorid, gift.Giftid, gift.Count, gift.ActualSpend/100, util.GetCoinName(gift.SpendType)),

		Resid:      gift.Giftid,
		Count:      gift.Count,
		CreateTime: gift.CreateTime,
		CoinType:   gift.SpendType,

		OrderNo: util.GenOrderId("GS", 1),
		Liveid:  gift.Liveid,
	}
	var profitLog []*models_main.UserProfit
	global2.Log.Debugf("%s写收益记录送礼方:%v", fName, userProfit)
	if gift.Spend != 0 { //只有一种情况为0，送的是活动礼物就不记userProfit
		profitLog = append(profitLog, userProfit)
	}
	//写入主播收益记录
	//if gift.SpendType == int(util.CoinDiamond) {
	anchorProfit := &models_main.UserProfit{
		//GiftLog{Giftid: r.Giftid, Anchorid: anchor.Id, Uid: uid, Liveid: liveInfo.Liveid,
		// Count: r.Count, Spend: giftPrint, SpendType: gift.PriceType,
		//CreateTime: timehelper.Now()}
		Uid:         gift.Anchorid, //记录的主人
		FUid:        gift.Uid,      //相关的人（送礼方）
		ConsumeType: _const.PROFIT_COMMISSION_ANCHOR,
		Type:        _const.TYPE_PROFIT, //这是一个赚钱记录

		CoinCount: gift.AnchorProfit,
		Content: fmt.Sprintf("收到礼物ID:%dx%d 礼物总金额%d%s 实际收礼金额%d%s",
			gift.Giftid, gift.Count, gift.Spend/100, util.GetCoinName(gift.SpendType), gift.ActualSpend/100, util.GetCoinName(gift.SpendType)),

		Resid:      gift.Giftid,
		Count:      gift.Count,
		CreateTime: gift.CreateTime,
		CoinType:   gift.SpendType,
		OrderNo:    util.GenOrderId("GR", 1),
		Liveid:     gift.Liveid,
	}
	profitLog = append(profitLog, anchorProfit)
	global2.Log.Debugf("%s写收益记录收礼方:%v", fName, anchorProfit)
	//}

	if err := InsertUserProfitByTransactions(global2.GetX(), profitLog); err != nil {
		global2.Log.Error("%s主播收益记录写入失败:%v", fName, profitLog)
	}
}

/**
@Origin: Spicy
@提取: Enzo July 1 2022
*/

func InsertGiftLive(gift *models_main.GiftLog) (int, error) {
	fName := "InsertGiftLive"
	gift.Id = 0
	session := global2.Live().Begin()
	giftLogId, err := InsertLogByTx(session, gift)
	if err != nil {
		global2.Log.Errorf("6InsertGift9送礼记录%v写入失败,%v", gift, err)
		session.Rollback()
		return 0, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	if err := session.Commit().Error; err != nil {
		session.Rollback()
		return 0, fmt.Errorf("%s%s", util.Convert(fName), err.Error())
	}
	return giftLogId, nil
}

func GetUserDiscount(uid int) *models_main.TempNoble {
	giftDiscount := &models_main.TempNoble{}
	global2.GetR().Raw("select if(SUM(gift_discount) is null,100,gift_discount) gift_discount,name from(SELECT gift_discount gift_discount,name FROM `db_noble_new` t1,"+
		"db_noble_record t2 where t2.noble_id=t1.id and  t2.uid=? and expiration>unix_timestamp(now()) ORDER BY t1.id desc LIMIT 1)a1", uid).Scan(&giftDiscount)
	return giftDiscount
}

/**
 * @Author admin
 * @Description //
 * @Date 18:31 2022/9/28
 * @Param
 * @return
 **/
func UpdateGiftLogOperateId(operateId string) int64 {
	return global2.GetX().Raw("update db_gift_log t1,(select id  from db_gift_log where operate_type=0 or (operate_type=1  and operate_time<=DATE_ADD(now(), INTERVAL -3 HOUR)) order by id LIMIT 30)t2 set  t1.operate_id=?,t1.operate_type=1,t1.operate_time=now() where t1.id=t2.id ", operateId).RowsAffected
}

/**
 * @Author admin
 * @Description //TODO
 * @Date 13:23 2022/10/3
 * @Param
 * @return
 **/
func QueryByExpired() []*models_main.GiftLog {
	o := make([]*models_main.GiftLog, 0)
	global2.GetX().Raw("select * from db_gift_log where operate_type=0  and operate_time<=DATE_ADD(now(), INTERVAL -1 HOUR)").Scan(&o)
	return o
}

/**
 * @Author admin
 * @Description //
 * @Date 18:31 2022/9/28
 * @Param
 * @return
 **/
func GetGiftLogList(operateId string) []*models_main.GiftLog {
	o := make([]*models_main.GiftLog, 0)
	global2.GetX().Raw("select * from db_gift_log where operate_id=?", operateId).Scan(&o)
	return o
}

/**
 * @Author admin
 * @Description //TODO
 * @Date 13:58 2022/9/29
 * @Param
 * @return
 **/
func UpdateGiftLogById(id int, session *gorm.DB) int64 {
	return session.Exec("update db_gift_log set operate_type=2 where id=? and operate_type=1", id).RowsAffected
}

func UpdateGiftLogByIdConfirm(operateId string) (int64, error) {
	db := global2.GetX().Exec("update db_gift_log set operate_type=1 where operate_id=? and operate_type=0", operateId)
	if db.Error != nil {
		return 0, db.Error
	}
	return db.RowsAffected, nil

}
